#include "WrappedPetsc.h"

#include <petscdm.h>
#include <petscis.h>
#include <petscksp.h>
#include <petscmat.h>
#include <petscpc.h>
#include <petscsf.h>
#include <petscsnes.h>
#include <petscvec.h>
#include <petscviewer.h>

// PetscSection got its own header file in 3.12, prior to that it was
// defined in petscis.h
#if !PETSC_VERSION_LT(3, 12, 0)
#   include <petscsection.h>
#endif

using namespace SG::Algebra;

// Specializations of the destroy() method for different PETSc classes
// This could also be macro-ized, but maybe it's not necessary?
template <>
void WrappedPetsc<Vec>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, VecDestroy (&obj));
}

template <>
void WrappedPetsc<KSP>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, KSPDestroy (&obj));
}

template <>
void WrappedPetsc<IS>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, ISDestroy (&obj));
}

template <>
void WrappedPetsc<Mat>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, MatDestroy (&obj));
}

template <>
void WrappedPetsc<VecScatter>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, VecScatterDestroy (&obj));
}

template <>
void WrappedPetsc<PetscViewer>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, PetscViewerDestroy (&obj));
}

template <>
void WrappedPetsc<MatNullSpace>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, MatNullSpaceDestroy (&obj));
}

template <>
void WrappedPetsc<DM>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, DMDestroy (&obj));
}

template <>
void WrappedPetsc<MatPartitioning>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, MatPartitioningDestroy (&obj));
}

template <>
void WrappedPetsc<SNES>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, SNESDestroy (&obj));
}

template <>
void WrappedPetsc<PC>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, PCDestroy (&obj));
}

template <>
void WrappedPetsc<PetscSection>::destroy ()
{
    CHKERRV (PETSC_COMM_SELF, PetscSectionDestroy (&obj));
}